const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d', {
  willReadFrequently: true
})
let isFirst = true
canvas.width = window.innerWidth * devicePixelRatio
canvas.height = window.innerHeight * devicePixelRatio

function getRandom(min, max) {
  return Math.floor(Math.random() * (max + 1 - min) + min)
}

class Particle {
  constructor(duration = 500) {
    const r = Math.min(canvas.width, canvas.height) / 2 // 半径
    const cx = canvas.width / 2 // x中心点
    const cy = canvas.height / 2 // y中心点
    const rad = (getRandom(0, 360) * Math.PI) / 180
    this.duration = duration
    this.x = cx + r * Math.cos(rad)
    this.y = cy + r * Math.sin(rad)
    this.size = getRandom(2 * devicePixelRatio, 7 * devicePixelRatio)
  }
  draw() {
    ctx.beginPath()
    ctx.arc(this.x, this.y, this.size, 0, 2 * Math.PI)
    ctx.fillStyle = '#5445544d'
    ctx.fill()
  }
  moveTo(tx, ty) {
    const sx = this.x,
      sy = this.y
    const xSped = (tx - sx) / this.duration
    const ySped = (ty - sy) / this.duration
    const startTime = Date.now()
    const _move = () => {
      const t = Date.now() - startTime
      const x = sx + xSped * t
      const y = sy + ySped * t
      this.x = x
      this.y = y
      if (t >= this.duration) {
        this.x = tx
        this.y = ty
        return
      }
      requestAnimationFrame(_move)
    }
    _move()
  }
}

const particles = []

let text = getText()

function clear() {
  ctx.clearRect(0, 0, canvas.width, canvas.height)
}

function draw() {
  clear()
  update()
  particles.forEach(p => p.draw())
  requestAnimationFrame(draw)
}

draw()

function getText() {
  return new Date().toTimeString().substring(0, 8)
}

function update() {
  const newText = getText()
  if (newText === text) {
    return
  }
  clear()
  text = newText
  ctx.fillStyle = '#000'
  ctx.textBaseLine = 'middle'
  ctx.font = `${140 * devicePixelRatio}px 'DS-Digital', sans-serif`
  const width = ctx.measureText(text).width
  ctx.fillText(text, (canvas.width - width) / 2, canvas.height / 2)
  const points = getPoints()
  clear()
  for (let i = 0; i < points.length; i++) {
    let p = particles[i]
    if (!p) {
      p = new Particle(isFirst ? 500 : 0)
      particles.push(p)
    }
    const [x, y] = points[i]
    p.moveTo(x, y)
  }
  if (points.length < particles.length) {
    particles.splice(points.length)
  }
  // isFirst = false
}

function getPoints() {
  const { width, height, data } = ctx.getImageData(
    0,
    0,
    canvas.width,
    canvas.height
  )
  const points = []
  const gap = 8
  for (let i = 0; i < width; i += gap) {
    for (let j = 0; j < height; j++) {
      const index = (i + j * width) * 4
      const r = data[index]
      const g = data[index + 1]
      const b = data[index + 2]
      const a = data[index + 3]
      if (r === 0 && g === 0 && b === 0 && a === 255) {
        points.push([i, j])
      }
    }
  }
  return points
}
